/*=====================================================================

  File:      StoreStreamPush.cs
  Summary:   SQL Remote Blob Storage sample application - StoreStreamPush.
             Sample application used to store data demonstrating the 
             streaming push methods.
             Blob Storage libraries.
  Date:      July 23st, 2008

---------------------------------------------------------------------

  This file is part of the Microsoft SQL Server Code Samples.
  Copyright (C) Microsoft Corporation.  All rights reserved.

This source code is intended only as a supplement to Microsoft
Development Tools and/or on-line documentation.  See these other
materials for detailed information regarding Microsoft code samples.

THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

======================================================= */

using System;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Transactions;

using Microsoft.Data.SqlRemoteBlobs;

namespace Microsoft.Samples.RemoteBlobStorage
{
    /// <summary>
    /// Sample Remote Blob Storage Application.
    /// </summary>
    public
    sealed
    class StoreStreamPush
    {
        private StoreStreamPush() { }

        public
        static
        void RunStoreStreamPush(string connectionString)
        {
            Console.WriteLine("Running the Store Stream Push Sample");

            // Basic write blob. Uses the default store and default collection.
            //
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();

                // Create a stream to read data from. Here this is a memory stream, however it 
                // could be a FileStream or other .NET Stream class.
                //
                byte[] blobData = Encoding.Unicode.GetBytes("Remote Blob Storage Sample Application Store Stream Push Test Data");
                using (MemoryStream dataStream = new MemoryStream(blobData))
                {
                    // Create a blob context to operate againt RBS.
                    //
                    SqlRemoteBlobContext blobContext = new SqlRemoteBlobContext(conn);

                    // Create a new blob.
                    //
                    using (SqlRemoteBlob blob = blobContext.CreateNewBlob())
                    {
                        // The SqlRemoteBlob object inherits from System.IO.Stream and can be used as such.
                        // Here we 'push' the contents of our dataStream into the blob stream.
                        //
                        int bufferLength = 256;
                        byte[] buffer = new byte[bufferLength];
                        int bytesRead = dataStream.Read(buffer, 0, bufferLength);

                        while (bytesRead > 0)
                        {
                            blob.Write(buffer, 0, bytesRead);
                            bytesRead = dataStream.Read(buffer, 0, bufferLength);
                        }

                        // Call commit to indicate we're done writing to the stream.
                        //
                        blob.Commit();

                        // Once all the data has been written to the blob, the next step is to register the blob 
                        // with the RBS auxiliary tables and insert the blob into the user application's metadata
                        // tables. This registration happens automatically when SqlRemoteBlob.GetBlobId is called.
                        // Make sure this registration and the application insert is wrapped in the same transaction.
                        //
                        using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
                        {
                            // Enlist the connection into the transaction.
                            //
                            conn.EnlistTransaction(Transaction.Current);

                            Console.WriteLine("Created Blob ID: {0}", BitConverter.ToString(blob.GetBlobId()));

                            // Add a new row including the blob ID to the database table.
                            //
                            string addBlobEntry = @" 
                                insert into 
                                    ApplicationSampleTable (SearchTags, BlobId) 
                                values 
                                    ('Sample, RBS, Demo', @blobId)
                            ";

                            using (SqlCommand cmd = new SqlCommand(addBlobEntry, conn))
                            {
                                cmd.Parameters.Add(new SqlParameter("@blobId", blob.GetBlobId()));
                                cmd.ExecuteNonQuery();
                            }
                            Console.WriteLine("Blob ID successfully stored in the application sample table.");
                            ts.Complete();
                        }
                    }

                    // Success
                    //
                }
            }
        }
    }
}
